v0で楽譜読み練習アプリを作ってみた
生成AIが進化すると、そのうちコードを書けない人でもアプリを作れるようになりそう、という話を最近雑談でしていました。そこまで行かなくても、開発をより効率的にしてくれます。
現状でどの程度までwebアプリを生成できるか気になって試してみました。
vercelが提供するUI生成AIのv0を使って、譜読み練習アプリの制作に挑戦してみます。
ゲーム要素もありロジックも考えないといけません。v0はUI生成AIなので、ロジック部分が複雑なアプリの生成には不向きかもしれませんが検証としてやってみます。
出来上がったアプリ
最終的に出来上がったwebアプリは以下です。UI作成や大半のロジックはv0に任せていますが、デバックやリファクタは自分が手動でやってます。
制作過程
まずはピアノの鍵盤や楽譜のUIを作成してもらい、音符の音階も変更できるようにお願いしました。いい感じにUIを作ってくれて、update notesを押すと音階も変わりました。
アプリのデザインを決めてなくても、一瞬で作ってくれるのでアプリのイメージが湧きやすいです。
この後「音符の形を四分音符に近づけてください」が上手く反映されなかったのですが、再生成すると出来ました。
ド、レ、ミまで鍵盤を押して、それに沿って音符が赤くなった様子のスクショです。手動で作るよりずっと簡単にできました。
以下のスクショは、「ゲームクリアを表す華やかな演出を実装してください」と少し抽象的にお願いした結果です。アニメーション付きで表示され、デザインも悪くは無いかなと思いました。個人開発程度であれば細かいデザインまで決めずにv0で実装してみるのもいいなって思いました。
指示を出すと毎回実装してくれますが、実装は無しで新機能の提案のみをお願いすると、その通りにしてくれました。難易度設定や正解率の表示、時間制限など色々案を出してくれました。
上手くいかなかった部分
ここまではほぼ問題なく作れましたが、思い通りに生成されない箇所もありました。
- 音符が綺麗に5線に乗らない
- 何度か試しましたが上手くいきません。でもcssだけで楽譜を綺麗に表現するのは人間でも難しいです。最終的に楽譜表示ライブラリを使うことにしました。
- ト音記号の表示をお願いしたら、小さな絵文字のト音記号(𝄞)が表示されるだけだった
- アセット画像を自動で用意することは出来なかったです。
- 音符の数を5つにお願いしても、3つ表示された
- 再生成も試したけど数字周りは苦手なのか、手動で変更した方が早かったです。
- warningが出てる
- Each child in a list should have a unique "key" prop.
- forを回して複数要素を作る場合に、要素ごとに異なるkeyを渡さないと出る警告です。警告が出ないように配慮してくれると助かります。
エラーの具体例
以下はリセット機能の実装をお願いして生成されたコードで、エラーが出て動きませんでした。
resetGame内で呼び出すsetNotes関数がスコープ外なのでundefinedとなりエラーが出ています。割と当たり前なミスをしてますね。
const resetGame = () => {
setNotes(generateRandomNotes(5))
setCurrentNoteIndex(0)
setShowCelebration(false)
}
export default function Home() {
const [notes, setNotes] = useState(generateRandomNotes(5));
const [currentNoteIndex, setCurrentNoteIndex] = useState(0);
const [showCelebration, setShowCelebration] = useState(false);
// ここにresetGame()関数を書くのが正しい
...
}
生成したコードでエラーが発生した場合、自分でデバッグするか、または再生成するだけでも意外と上手くいくことが多かったです。
楽譜ライブラリを導入してみる
次に楽譜表示ライブラリ(vexflow)を使って楽譜を表示するようにお願いしてみました。このライブラリ選定もv0にやってもらっています。
ここまででも以下のようなコードをv0が考えてくれていて、かなり効率化できていると思います。
- ピアノ、クリア演出、楽譜などの各コンポーネントの作成
- ランダムな音階の音符を生成する関数
- ピアノで押された音階と楽譜上の音符が一致するか条件分岐
- 音符の色を変えるため、useEffectで再レンダリングする仕組み
- ピアノと楽譜、クリアなどに関する状態管理
- 各コンポーネント間の状態の受け渡し
v0で生成したコードは、ローカルからnpx shadcnで取り込むことができます。
npx shadcn@latest add "https://v0.dev/chat/b/xxx"
エラーの内容
一方で、ライブラリ導入後にもエラーが出ていて手動でデバッグが必要でした。エラーの内容は以下のようなものでした。
- 関数に渡す引数が間違っていてエラー
- 4/4拍子に合った音符を表す文字列を渡さないといけないのに、音符の数が少ない
- 楽譜のサイズ変更時にも引数が間違っていた。ある関数に渡すべき引数を、一行手間で出てくる別の関数に渡していた
- 音符を赤くする処理が出来ていない
- querySelectorに渡す要素のidが間違っていた。この実装方法自体は役立ちました。
- 型エラーが出ている
- 楽譜をレンダリングしたい要素のidの文字列で渡すべきところを、HTMLDivElementを渡していた。一応問題なく動いてはいました。
これらのエラーはプロンプトで指摘しても修正できませんでした。
しかし、vexflowのドキュメントや記事は探せば出てきますがマイナーなライブラリだと思います。あと機能が増えてきてコードも複雑になってます。楽譜周りだとエラーが出やすかったですが、仕方ないかなと思います。
不便だった点
- デバッグしずらい
- v0のブラウザ上のエディターだと、エラー文が表示されずデバッグがしづらかったです。もともとUI生成AIと書かれているのでブラウザ上のみでがっつり開発することは想定されていないのかな、と思います。
- v0のエディタからは新規ファイルが作成できない
- 自分でエディタ上からファイルやフォルダーの新規作成ができず、v0にプロンプトでお願いしないといけませんでした。
- 変更点をgitにコミットするのもブラウザ上では行えず、gitの変更をpullしてくることもできません。ローカルでの変更をv0に反映することが出来ないのは不便でした。
- 自分で最適化やリファクタが必要
- 関数のmemo化など考慮されていない箇所があり、手動で直しました。最適化して下さい、などをお願いしたら良いのかもしれませんが、自発的にやってくれると助かります。
- ネストしたif文など読みづらいのでオブジェクトマップやswitch文に置き換えたり、長い配列データを別ファイルに切り出したりなどのリファクタを自分で行いました。それでも思ったよりは綺麗なコードを書いてくれました。
機能やコードが増えて複雑になってくるとエラーが出やすかったり、エラーが出なくても人間ならすぐに気づける違和感にv0は気づいてくれません。v0は部分的にUI生成を行い、その変更内容をローカルに取り込むという程度の使い方が良いのかもしれません。
それでもv0のおかげで開発をかなり効率化できました!個人開発で最初はv0使って作るとかなら、一瞬でUIが生成されるのでイメージが湧きやすくモチベーションも上がるのでおすすめです!